package pw_coding

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"sasuke/config"
	"sasuke/pw_date"
	"sasuke/utils"
	"xorm.io/xorm"
)

func PumpFromMysql(pm *CmdParam, typefunc func(string, bool) string) []EntityStruct {
	connStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/information_schema?charset=utf8mb4", pm.User, pm.Pwd, pm.Ip, pm.Port)
	var tbs []TABLES
	es := make([]EntityStruct, 0)
	x, err := xorm.NewEngine("mysql", connStr)
	if err != nil {
		fmt.Printf("数据库连接失败:", err)
	}
	x.Table("TABLES").Where("TABLES.TABLE_SCHEMA=?", pm.Code).Find(&tbs)
	for index, table := range tbs {
		entity := table2entity(table)
		refs := make(map[string]string, 0)
		var cols []COLUMNS
		x.Table("COLUMNS").Where("COLUMNS.TABLE_SCHEMA=?", pm.Code).And("COLUMNS.TABLE_NAME=?", table.TABLE_NAME).Find(&cols)
		fmt.Println("抽取数据表标号：", index)
		props := make([]PropertyStruct, 0)
		for _, col := range cols {
			if col.DATA_TYPE == "date" || col.DATA_TYPE == "datetime" {
				if _, ok := refs[col.DATA_TYPE]; !ok {
					refs[col.DATA_TYPE] = "time"
				}
			}
			if col.DATA_TYPE == "decimal" {
				if _, ok := refs[col.DATA_TYPE]; !ok {
					refs[col.DATA_TYPE] = "github.com/shopspring/decimal"
				}
			}
			if col.IS_NULLABLE == "YES" {
				if _, ok := refs["YES"]; !ok {
					refs["YES"] = "database/sql"
				}
			}
			p := column2property(col, typefunc)
			props = append(props, *p)
		}
		entity.Package = pm.Code
		entity.HasProp = len(props) > 0
		// TODO: 暂未相当多语言共同的引用方案， 待以后优化
		entity.HasReference = pm.Language == "go" && len(refs) > 0
		entity.References = mapToSlice(refs)
		entity.Props = props
		entity.Author = config.TOOL_AUTHOR
		entity.CreatedDate = pw_date.PW_Now_New().NormalFmt()
		es = append(es, *entity)
	}
	return es
}
func table2entity(tb TABLES) *EntityStruct {
	dto := &EntityStruct{}
	dto.Name = utils.Capitalize(tb.TABLE_NAME)
	dto.DbName = tb.TABLE_NAME
	dto.Annotation = tb.TABLE_COMMENT
	return dto
}
func column2property(col COLUMNS, typefunc func(string, bool) string) *PropertyStruct {
	dto := &PropertyStruct{}
	dto.DbName = col.COLUMN_NAME
	dto.Name = utils.Capitalize(col.COLUMN_NAME)
	dto.Annotation = col.COLUMN_COMMENT
	cannull := col.IS_NULLABLE == "YES"
	dto.CanNull = cannull
	dto.TypeName = typefunc(col.DATA_TYPE, cannull)
	dto.DbTypeName = col.DATA_TYPE
	dto.DbTypeFull = col.COLUMN_TYPE
	if col.CHARACTER_MAXIMUM_LENGTH.Valid {
		dto.MaxLength = col.CHARACTER_MAXIMUM_LENGTH.Int64
	}
	if col.NUMERIC_PRECISION.Valid {
		dto.NumericPrecision = col.NUMERIC_PRECISION.Int64
	}
	if col.NUMERIC_SCALE.Valid {
		dto.NumericScale = col.NUMERIC_SCALE.Int64
	}
	return dto
}
func mapToSlice(m map[string]string) []string {
	s := make([]string, 0, len(m))
	for _, v := range m {
		s = append(s, v)
	}
	return s
}
